class MapCell {
    constructor(map, row, col, role) {
        this.row = row;
        this.col = col;
        this.role = role;
        this.last_map_cell = null;
        this.distance = Infinity;
        this.map = map;
    }

    reset_cell(role) {
        this.role = role || 1;
        this.last_map_cell = null;
        this.distance = Infinity;
    }

    find_mark_next() {
        let map = this.map;
        if (this.row > 0) {
            this.mark_next_map_cell(this.row - 1, this.col);
        }
        if (this.row < map.map_size - 1) {
            this.mark_next_map_cell(this.row + 1, this.col);
        }
        if (this.col > 0) {
            this.mark_next_map_cell(this.row, this.col - 1);
        }
        if (this.col < map.map_size - 1) {
            this.mark_next_map_cell(this.row, this.col + 1);
        }
    };

    mark_next_map_cell(next_row, next_col) {
        let map = this.map;
        let next_map_cell = map.row_col_2_vector(next_row, next_col);
        if (next_map_cell.role === 1) {
            if (this.distance + 1 < next_map_cell.distance) {
                next_map_cell.last_map_cell = this;
                next_map_cell.distance = this.distance + 1;
            }
        }
    };

    get_center_xy() {
        let map_info = this.map.map_info;
        let {cell_width, cell_height} = map_info;
        let x = cell_width * this.col + cell_width / 2;
        let y = cell_height * this.row + cell_height / 2;
        return [x, y];
    };

    get_start_xy() {
        let map_info = this.map.map_info;
        let {cell_width, cell_height} = map_info;
        let x = cell_width * this.col;
        let y = cell_height * this.row;
        return [x, y];
    };

    is_start_end_cell() {
        let cell1 = this.map.start_cell;
        let cell2 = this.map.end_cell;
        return (this.row === cell1.row && this.col === cell1.col) ||
            (this.row === cell2.row && this.col === cell2.col);
    };

    draw_mark(mark_type, frame_index) {
        let map_info = this.map.map_info;
        let ctx = map_info.ctx_map;
        let {cell_width, cell_height} = map_info;
        let start_xy = this.get_start_xy();
        let [x, y] = start_xy;
        let trim = 10;
        ctx.lineCap = "round";
        let width41 = cell_width / 4;
        let width31 = cell_width / 2.5 | 0;

        switch (mark_type) {
            case "wall":
                ctx.fillStyle = "#999";
                ctx.strokeStyle = "#666";
                ctx.strokeRect(x, y, cell_width, cell_height);
                ctx.fillRect(x, y, cell_width, cell_height);

                ctx.fillStyle = "#666";
                ctx.fillRect(x + width41, y + width41, cell_width - width41 * 2, cell_height - width41 * 2);
                break;
            case "preview":
                ctx.fillStyle = "rgba(50, 50, 50, 0.3)";
                ctx.fillRect(x + 5, y + 5, cell_width - 10, cell_height - 10);
                break;
            case "path":
                ctx.fillStyle = frame_index ? "rgba(0, 255, 0, 0.1)" : "rgba(0, 255, 0, 0.3)";
                ctx.fillRect(x + width31, y + width31, cell_width - width31 * 2, cell_height - width31 * 2);
                break;
            case "drop":
                ctx.strokeStyle = "#ff0000";
                ctx.lineWidth = 10;
                ctx.beginPath();
                ctx.moveTo(x + trim, y + trim);
                ctx.lineTo(x + cell_width - trim, y + cell_height - trim);
                ctx.moveTo(x + cell_width - trim, y + trim);
                ctx.lineTo(x + trim, y + cell_height - trim);
                ctx.stroke();
                break;
            case "deny":
                ctx.strokeStyle = "rgba(255, 0, 0, 0.5)";
                ctx.lineWidth = 5;
                ctx.beginPath();
                ctx.moveTo(x + trim, y + trim);
                ctx.lineTo(x + cell_width - trim, y + cell_height - trim);
                ctx.moveTo(x + cell_width - trim, y + trim);
                ctx.lineTo(x + trim, y + cell_height - trim);
                ctx.stroke();
                break;
            case "empty":
                ctx.lineWidth = 3;
                ctx.setLineDash([6, 6]);
                ctx.strokeStyle = "#666";
                ctx.strokeRect(x + 1, y + 1, cell_width - 2, cell_height - 2);
                ctx.setLineDash([]);
                break;
        }
        ctx.lineWidth = 1;
    };
}

export default MapCell;